# -*- coding: utf-8 -*

from MyClasses.MyMailer import MyMailer
import MyClasses.MyConfigParser

import imaplib

from unittest import TestCase
from mock import patch, Mock

class MyMailerTest(TestCase):

	@patch('MyClasses.MyConfigParser')
	def connect_test(self, my_config_parser):
		assert MyClasses.MyConfigParser is my_config_parser

		mcp = my_config_parser.MyConfigParser.return_value

		mcp.getHost.return_value  = 'localhost'
		mcp.getPort.return_value  = '993'

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.connect()
			imap_mock.assert_called_once_with('localhost', '993')

		with patch('imaplib.IMAP4_SSL', side_effect=Exception("Some error")) as imap_mock:
			m = MyMailer()
			self.assertRaises(Exception, m.connect)

	@patch('MyClasses.MyConfigParser')
	def login_test(self, my_config_parser):
		assert MyClasses.MyConfigParser is my_config_parser
		#assert imaplib.IMAP4_SSL is imap

		mcp = my_config_parser.MyConfigParser.return_value

		mcp.getUser.return_value  = 'username'
		mcp.getPass.return_value  = 'testpassword'

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.login.return_value = ('OK',['LOGIN completed'])
			m.imap.select.return_value = ('OK', ['X'])
			
			m.login()
			imap_mock.return_value.login.assert_called_once_with('username', 'testpassword')

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.login.side_effect = imaplib.IMAP4.error
		
			self.assertRaises( imaplib.IMAP4.error, m.login)

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.select.return_value = ('OK', ['X'])

			m.login()
			m.imap.select.assert_called_once_with()

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.select.return_value = ('NO', ['[UNAVAILABLE] SELECT backend error: unknown reason. sc=pssw5pvnxOsF'])

			self.assertRaises( Exception, m.login)

	@patch('MyClasses.MyConfigParser')
	def search_test(self, my_config_parser ):
		positive_header = ('OK', [('2 (BODY[TEXT] {88}', '<div>\xfc\xd4\xcf \xd4\xc5\xd3\xd4\xcf\xd7\xcf\xc5 \xd0\xc9\xd3\xd8\xcd\xcf</div><div>\x9a</div><div>-- <br />\xf3 \xd5\xd7\xc1\xd6\xc5\xce\xc9\xc5\xcd<br />\xf1\xd2\xcf\xd3\xcc\xc1\xd7</div>\r\n'), ')'])
		positive_body = 	('OK', [('2 (BODY[HEADER] {1734}', 'Date: Sat, 22 Dec 2012 20:08:42 +0400\r\nContent-Type: text/html; charset=koi8-r\r\nReturn-Path: d4rk5eed@yandex.ru\r\n\r\n'), ')'])

		assert MyClasses.MyConfigParser is my_config_parser
		#assert imaplib.IMAP4_SSL is imap

		mcp = my_config_parser.return_value

		mcp.getUser.return_value  = 'username'
		mcp.getPass.return_value  = 'testpassword'

		#позитивная ветка
		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.search.return_value = ('OK',['1 2'])
		
			m.search('ABC','22-Dec-2012')

			imap_mock.return_value.search.assert_called_once_with('UTF-8', 'SUBJECT', 'ABC', 'ON', '22-Dec-2012')


		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			m.imap.search.return_value = ('OK',['1 2'])

			m.fetch = Mock()

			result_list = m.search('ABC','22-Dec-2012')
			self.assertEquals(m.fetch.call_count, 2)

		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			
			m.imap.search.return_value = ('OK', ['1 2'])

			m.fetch = Mock()

			m.fetch.return_value = (positive_header[1][0][1], positive_body[1][0][1])

			result_list = m.search('ABC','22-Dec-2012')

			self.assertEquals( result_list, [(positive_header[1][0][1], positive_body[1][0][1]),(positive_header[1][0][1], positive_body[1][0][1])])

		#негативная ветка
		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			
			m.imap.search.return_value = ('OK',[None])

			result_list = m.search('ABC','22-Dec-2012')

			self.assertFalse( result_list, False)

		#ветка с ответом отличным от OK
		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			
			m.imap.search.return_value = ('ERROR')

			self.assertRaises( Exception, m.search, ('ABC','22-Dec-2012'))

		#ветка с исключением
		with patch('imaplib.IMAP4_SSL') as imap_mock:
			m = MyMailer()
			m.imap = imap_mock.return_value
			
			m.imap.search.side_effect = Exception("Boom!")

			self.assertRaises( Exception, m.search, ('ABC','22-Dec-2012'))

if __name__ == "__main__":
	unittest.main()